<?php
namespace app\open\model;
use app\common\model\OpenBase;

class UserIm extends OpenBase {
	protected $tableName = 'im_user'; //user信息表
	//定义字段信息
	protected $fields = [
		0 => 'id',
		1 => 'local_uid', //用户UID
		2 => 'uname',
		3 => 'password',
		4 => 'created',
		5 => 'updated',
		6 => 'im_uid',
		7 => 'disabled',
	];
	//设置自动填充的数据
	protected $auto = ['created' => NOW_TIME, 'disabled' => 0];
	//定义请求header
	protected $header = [
		'XAuthToken' => '123456',
		'100Continue' => 'Expect:',
	];
	//请求的类型别名定义
	protected $response_type = [
		'post' => ['post', 'add'],
		'put' => ['put', 'update', 'save'],
		'delete' => ['delete'],
		'get' => ['get', 'select'],
	];
	protected $urls = [
		'users' => 'http://58.64.176.44:9501/users',
		'conversation' => 'http://58.64.176.44:9501/conversation',
		'member' => 'http://58.64.176.44:9501/conversation/member',
		'limited' => 'http://58.64.176.44:9501/conversation/member/limited',
	];
	//初始化方法
	protected function _initialize() {
	}
	/**
	 * @name call方法
	 */
	public function __call($method, $params) {
		$type = '';
		if (strtolower(substr($method, 0, 6)) == 'imuser') {
			//取得类型
			$type = self::parseName(substr($method, 6))[0];
			$url = $this->urls['users'];

		} elseif (strtolower(substr($method, 0, 12)) == 'conversation') {
			//取得类型
			$type = self::parseName(substr($method, 12))[0];
			$url = $this->urls['conversation'];
		} elseif (strtolower(substr($method, 0, 7)) == 'limited') {
			//取得类型
			$type = self::parseName(substr($method, 7))[0];
			$url = $this->urls['limited'];
		}
		if ($url) {
			$type = strtolower($type);
			foreach ($this->response_type as $k => $v) {
				if (in_array($type, $v)) {
					return self::request($k, $params[0], $url);
				}
			}
		}

		//接口不存在
		return getApiErrorCode('00404');
	}

	/**
	 * @name 解析name
	 * @param string $name
	 * @return array 返回name和类型
	 */
	private static function parseName($name) {
		return strpos($name, '/') ? explode('/', $name, 2) : [$name];
	}
	/**
	 * @name 本地数据验证(过滤和自动填充数据)
	 * @author martinsun syh@sunyonghong.com
	 * @access protected
	 * @param array $data 验证的数据数组
	 * @param boolean $auto 是否自动填充数据
	 * @return array 验证后的数据
	 */
	protected function validateData($data = [], $auto = false) {
		if (!$data || !is_array($data)) {
			return false;
		}

		$res = [];
		$this->fields = $this->fields ?: $this->getFields();
		$data['local_uid'] = $data['uid'];
		foreach ($data as $k => $v) {
			in_array($k, $this->fields) && $res[$k] = $v;
		}
		if ($auto && !empty($this->auto)) {
			return array_merge($res, $this->auto);
		}
		return $res;
	}
	/**
	 * @name 获取IM用户
	 * @param int $uid 用户UID
	 * @return array IM用户的登陆口令
	 */
	public function getImUser($uid = 0) {
		if (!$uid) {
			return [];
		}

		$this->tableName = 'im_user';
		$this->duplicate = [];
		$imUser = $this->where(['local_uid' => $uid])->field(['im_uid', 'password'])->find();
		if ($imUser) {
			$imUser['im_uid'] = (int) $imUser['im_uid'];
			$imUser['im_pwd'] = $imUser['password'];
			unset($imUser['password']);
		} else {
			$imUser = [];
		}
		return $imUser;
	}
	/**
	 * @name 创建IM用户
	 * @param array $data 用户数据信息
	 * @desc data中包含
	 *      int uid 本地用户UID(必须)
	 *      int im_uid(指IMserver上的用户UID-自己定义)(必须)
	 *      string password 用户密码(必须),不超过32位
	 *      string uname  imserver的用户昵称 (可选)
	 * @return array IM用户的登陆口令
	 */
	public function createImUser($data = []) {
		$data = self::validateData($data, true);
		if (!$data) {
			return false;
		}

		//检测是否已经注册,已经注册返回注册的信息
		$hasUser = self::getImUser($data['local_uid']);
		if (!empty($hasUser)) {
			return $hasUser;
		}
		//添加IMserver用户
		$imUser = [
			'uid' => (int) $data['im_uid'],
			'pwd' => $data['password'],
			'name' => $data['uname'],
		];
		if (!$imUser['pwd'] || !$imUser['uid']) {
			return [];
		}
		$re = self::request('post', $imUser, $this->urls['users']);
		if ($re['code'] == '200' && $this->add($data)) {
			return ['im_uid' => (int) $imUser['uid'], 'im_pwd' => $imUser['pwd']];
		} else {
			$this->error = '创建IM用户失败';
			return [];
		}
	}
	/**
	 * @name 更新IM用户信息
	 * @param array $data
	 * @desc $data 中包含以下参数
	 *       int uid  本地用户的UID
	 *       string name  需要修改的IMserver上的昵称
	 *       string pwd   需要修改的IMserver上的密码,不能超过32位
	 *       int disabled 是否禁用  1:是  0:否
	 * @return array IM用户的口令
	 */
	public function updateImUser($data = []) {
		$data = self::validateData($data, false);
		if (!$data) {
			return false;
		}

		//修改IMserver用户
		$imUser['uid'] = getImUID($data['local_uid']);
		$data['uname'] && $imUser['name'] = $data['uname'];
		$data['pwd'] && $imUser['pwd'] = $data['password'];
		(int) $data['disabled'] && $imUser['disabled'] = (int) $data['disabled'];
		$re = self::request('put', $imUser, $this->urls['users']);

		if ($re['code'] == '200') {
			$this->where('local_uid=' . $data['local_uid'])->save($data);
			return self::getImUser($data['local_uid']);
		} else {
			$this->error = '更新IM用户信息失败';
			return [];
		}
	}
	/**
	 * @name 调用IMserver服务操作
	 * @param string $type 请求的类型   [post,put,get,delete]
	 * @param array $params 请求时携带的参数
	 * @param string $url  请求的url
	 * @return array 请求后的返回数据
	 */
	protected function request($type = '', $params = [], $url = '') {
		if (!$type || !$url) {
			return [];
		}

		//加载httpful
		vendor('Bootstrap', VENDOR_PATH . 'Httpful' . DS);
		//初始化
		\Httpful\Bootstrap::init();
		//$url = $this->urls['users'];
		//参数拼接
		if (in_array($type, ['get', 'delete'])) {
			$url .= '?' . http_build_query($params);
			$send = \Httpful\Request::$type($url);
		} else {
			$send = \Httpful\Request::$type($url)
				->sendsForm()
				->body($params);
		}
		foreach ($this->header as $key => $val) {
			$fun = 'with' . $key;
			$send = $send->$fun($val);
		}
		$response = $send
			->expectsJson()
			->send();
		//数据转换为数组返回
		return object2array($response->body);
	}
    /**
     * @name 获取会话
     * @param array $map 获取的条件 
     * @desc $map 包含以下参数
     *       int uid 本地用户的uid 可选
     *       string affix 附加的扩展信息
     * @param boolean $auto_create 当本地没有记录的时候,是否自动创建
     * @return array 会话信息
     */
    public function getConversation($map = [],$auto_create = false){
        if(!is_array($map)) return [];
        $this->tableName = 'im_conversation';
        $map['uid'] && $map['local_uid'] = $map['uid'];
        unset($map['uid']);
        $has = $this->where($map)->field(['cid','type','local_uid'])->find();
        if($has['cid'] > 0){
            $data = ['cid'=>$has['cid']];
            $mc = self::request('get',$data,$this->urls['conversation']);
            $mc = $mc['data']['mc'] -1 > 0 ? $mc['data']['mc'] -1 : 0;
            return [
                //'name' => $has['name'],
                'cid'  => (int)$has['cid'],
                'im_uid' => getImUID($has['local_uid']),
                'mc'    => $mc,
            ];
        }else{
            if($auto_create === true){
                return self::createConversation($map);
            }
            return [
                //'name' => $has['name'],
                'cid'  => 0,
                'im_uid' => 0,
                'mc' => 0
            ];
        }
    }
	/**
	 * @name 创建会话
	 * @param array $data
	 * @desc $data 包含以下参数
	 *      int local_uid 本地用户UID
	 *      int type 创建的会话类型 0私聊、1群组、2聊天室、3系统
	 */
	public function createConversation($data = []) {
		$this->tableName = 'im_conversation';
		//定义字段信息
		$this->fields = [
			0 => 'id',
			1 => 'local_uid', //用户UID
			//2 => 'name',
			3 => 'cid',
			4 => 'type',
			5 => 'max_count',
			6 => 'affix',
			7 => 'ctime',
		];
		$this->auto = ['ctime' => NOW_TIME];
		$uid = $data['local_uid'];
		unset($data['local_uid']);
		if (!in_array($data['type'], [1, 2, 3, 4])) {
			return ['cid' => 0];
		}
		$re = self::request('post', $data, $this->urls['conversation']);
		if ($re['code'] == '200' && $re['data']['cid']) {
			$data = array_merge($re['data'], $data);
		} else {
			return ['cid' => 0];
		}
		$data = self::validateData($data, true);
		if (!$data) {
			return ['cid' => 0];
		}

		$data['local_uid'] = $uid;
		$where = [
			'local_uid' => $data['local_uid'],
			'type' => $data['type'],
			'ctime' => 0,
		];
		if ($this->where($where)->save($data) || $this->add($data)) {
			return [
				'cid' => (int) $data['cid'],
				'im_uid' => getImUID($data['local_uid']),
                'mc' => 0
			];
		} else {
			return ['cid' => 0, 'im_uid' => 0];
		}
	}

	/**
	 * @name 检测会话是否创建/存在(暂时未用到)
	 * @param boolean $only_local 是否仅本地验证
	 */
	public function hasConversation($map = [], $only_local = true) {
		if (!is_array($map)) {
			return [];
		}

		$this->tableName = 'im_conversation';
		if ($map['uid']) {
			$map['local_uid'] = $map['uid'];
			unset($map['uid']);
		}
		$has = $this->where($map)->count();
		//本地有记录
		if ($has > 0) {
			//是否需要验证imserver的真实情况
			if (!$only_local) {
				$cid = ['cid' => $map['cid']];
				$re = self::conversationGET($cid);
				return $re;
			}
			return true;
		}
	}

	/**
	 * @name 删除会话
	 */
	public function deleteConversation($data = []) {
		$sation = self::getConversation($data);
		if ($sation['cid'] <= 0) {
			return 0;
		}
		$table = M('im_conversation');
		//删除会话
		$res = self::conversationDELETE($sation);
		if ($res['code'] == '200' && $res['data'] == true) {
			//IMserver删除成功
			$data['uid'] && $data['local_uid'] = $data['uid'];
			unset($data['uid']);
			$save['ctime'] = 0;
			$save['cid'] = 0;
			if ($table->where($data)->save($save)) {
				return 1;
			}
		}
		return 0;

	}

	/**
	 * @name 检测当前用户是不是指定会话的管理员
	 */
	public function isAdminForSation($uid = 0, $cid = 0) {
		$this->tableName = '';
		if ($uid && $cid) {
			$map['local_uid'] = $uid;
			$map['cid'] = $cid;
			return M('im_conversation')->where($map)->count() > 0 ? true : false;
		}
		return false;
	}

}